using System;

namespace Utils
{
    /// <summary>
    /// 可观察值，提供值变更通知、验证和比较功能
    /// </summary>
    /// <typeparam name="T">属性值的类型</typeparam>
    public class ObservableValue<T>
    {
        private T _value;
        private Func<T, T, bool> _comparer; //比较器
        private Func<T, T> _validator; //验证器
        private bool _changeCheck = true; //变更检查

        /// <summary>
        /// 当属性值发生变化时触发的事件
        /// </summary>
        public event Action<T> OnValueChanged;

        /// <summary>
        /// 获取或设置属性值。设置时会进行验证、比较，并在值实际变化时触发事件
        /// </summary>
        public T Value
        {
            get => _value;
            set
            {
                var newValue = value;

                // 应用验证器（如果存在）
                if (_validator != null)
                    newValue = _validator.Invoke(newValue);

                // 检查值是否实际发生变化
                if (_changeCheck && Compare(_value, newValue))
                    return;

                // 更新值并触发变更事件
                _value = newValue;
                OnValueChanged?.Invoke(newValue);
            }
        }
        

        /// <summary>
        /// 初始化可观察属性的新实例
        /// </summary>
        /// <param name="value">属性的初始值</param>
        public ObservableValue(T value)
        {
            _value = value;
        }

        /// <summary>
        /// 比较两个值是否相等
        /// </summary>
        /// <param name="oldValue">旧值</param>
        /// <param name="newValue">新值</param>
        /// <returns>如果值相等返回true，否则返回false</returns>
        private bool Compare(T oldValue, T newValue)
        {
            if (_comparer != null)
                return _comparer.Invoke(oldValue, newValue);

            // 处理null值的情况
            if (oldValue == null)
                return newValue == null;

            return oldValue.Equals(newValue);
        }

        /// <summary>
        /// 设置自定义比较器，用于确定值是否发生变化
        /// </summary>
        /// <param name="comparer">比较函数，接受旧值和新值，返回是否相等</param>
        /// <returns>当前实例，支持链式调用</returns>
        public ObservableValue<T> WithComparer(Func<T, T, bool> comparer)
        {
            _comparer = comparer;
            return this;
        }

        /// <summary>
        /// 设置值验证器，用于在赋值前验证和修正值
        /// </summary>
        /// <param name="validator">验证函数，接受输入值，返回修正后的值</param>
        /// <returns>当前实例，支持链式调用</returns>
        public ObservableValue<T> WithValidator(Func<T, T> validator)
        {
            _validator = validator;
            return this;
        }

        /// <summary>
        /// 启用或禁用变更检查。禁用后每次赋值都会触发事件
        /// </summary>
        /// <param name="enable">是否启用变更检查</param>
        /// <returns>当前实例，支持链式调用</returns>
        public ObservableValue<T> WithChangeCheck(bool enable)
        {
            _changeCheck = enable;
            return this;
        }
    }
}